home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Gold Collection / Software Vault - The Gold Collection (American Databankers) (1993).ISO / cdr35 / dwnsrs57.zip / DOWNPAR.C < prev    next >
C/C++ Source or Header  |  1993-06-22  |  28KB  |  659 lines

  1. /* ============================================================= */
  2. /*  Rob Hamerling's MAXIMUS download file scan and sort utility. */
  3. /*  -> DOWNPAR.C                                                 */
  4. /*  -> Parameter processing routines for DOWNSORT.               */
  5. /* ============================================================= */
  6.  
  7. #define INCL_BASE
  8. #define INCL_NOPMAPI
  9. #define INCL_DOSNLS
  10. #include <os2.h>
  11.  
  12. #include <ctype.h>
  13. #include <memory.h>
  14. #include <stdio.h>
  15. #include <stdlib.h>
  16. #include <string.h>
  17. #include <time.h>
  18.  
  19. #include "..\max\mstruct.h"
  20. #include "downsort.h"
  21. #include "downfpro.h"
  22.  
  23. /*  Symbolic names of keyword parameters */
  24. #define    K_CMT      0
  25. #define    K_TIT      1
  26. #define    K_FNT      2
  27. #define    K_DAT      3
  28. #define    K_ALL      4
  29. #define    K_NEW      5
  30. #define    K_GBL      6
  31. #define    K_BBS      7
  32. #define    K_FIL      8
  33. #define    K_ORP      9
  34. #define    K_NNN     10
  35. #define    K_PRE     11
  36. #define    K_SUB     12
  37. #define    K_BOT     13
  38. #define    K_NDS     14
  39. #define    K_ODS     15
  40. #define    K_IPF     16
  41. #define    K_OFF     17
  42. #define    K_AIN     18
  43. #define    K_AEX     19
  44. #define    K_DUP     20
  45. #define    K_OK      21
  46. #define    K_IP2     22
  47. #define    K_ASQ     23
  48. #define    K_EMI     24
  49. #define    K_AVA     25
  50. #define    K_NDE     26
  51. #define    K_END    255
  52.  
  53. /* prototypes of local functions */
  54.  
  55. void    add_area_array(char *);
  56. void    add_ext_array(char *);
  57. short int conv_priv(char [], short int [], unsigned short int);
  58. void    list_parm(short int, char *, short int);
  59. short int parse_keyword(char [], char **);
  60. void    read_cfg(char *);
  61. void    title_line(char *, char *[]);
  62.  
  63.  
  64. /* ----------------------------------------- */
  65. /* Process commandline and system parameters */
  66. /* ----------------------------------------- */
  67. void get_parm(unsigned short int k,
  68.               char *p[])
  69. {
  70. #ifndef __32BIT__
  71.   unsigned short int x;
  72. #else
  73.   unsigned long int x;
  74. #endif
  75.   unsigned short int i,j,n;             /* counters                      */
  76.   char   c;                             /* option letter                 */
  77.  
  78. #ifndef __32BIT__
  79.   DosGetCtryInfo(sizeof(COUNTRYINFO), &c_code, &c_info, &x);
  80. #else
  81.   DosQueryCtryInfo(sizeof(COUNTRYINFO), &c_code, &c_info, &x);
  82. #endif
  83.                                         /* for date format, etc          */
  84.   sys_date(today);                      /* start timestamp               */
  85.  
  86.   for (i=1; i<k; ++i) {                 /* pre-scan                      */
  87.     if (p[i][0]=='@')                   /* config filespec               */
  88.       strncpy(cfg_path,strupr(&p[i][1]),127); /* copy filespec           */
  89.     else if (p[i][0] == '/' || p[i][0] == '-') { /* options              */
  90.       switch(c = (char) toupper(p[i][1])) {
  91.         case VERBOSE   : oper_mode = VERBOSE;   break;
  92.         case QUIET     : oper_mode = QUIET;     break;
  93.         case HELP      : oper_mode = HELP;      break;
  94.         case QMARK     : oper_mode = HELP;      break;
  95.         }
  96.       }
  97.     }
  98.  
  99.   if (oper_mode == HELP)
  100.     show_help();                        /* display help and exit         */
  101.   else if (oper_mode != QUIET)
  102.     show_welcome();                     /* display DOWNSORT 'logo'       */
  103.  
  104.   read_cfg(cfg_path);                   /* process configuration file    */
  105.  
  106.   for (i=1; i<k; i++) {                 /* all commandline parms         */
  107.     strupr(p[i]);                       /* make string upper case        */
  108.  
  109.     if (strcmp(p[i],"ORP") == 0)        /* ORP-list requested            */
  110.       lp[P_ORP].priv[0] = SYSOP;        /* first/only default: SYSOP     */
  111.  
  112.     else if (strcmp(p[i],"BBS") == 0 ||
  113.              strncmp(p[i],"BBS:",4) == 0) {  /* BBS-list requested       */
  114.       lp[P_BBS].priv[0] = SYSOP;        /* default: SYSOP                */
  115.       if (p[i][3] == ':')
  116.         if (conv_priv(&p[i][4],lp[P_BBS].priv,1) <= 0)   /* convert      */
  117.           oper_mode = HELP;
  118.       }
  119.  
  120.     else if (strcmp(p[i],"NEW") == 0 ||
  121.              strncmp(p[i],"NEW:",4) == 0) { /* NEW-list requested        */
  122.       lp[P_NEW].priv[0] = SYSOP;        /* first/only default: SYSOP     */
  123.       if (p[i][3] == ':')
  124.         if (conv_priv(&p[i][4],lp[P_NEW].priv,10) <= 0)  /* make int     */
  125.           oper_mode = HELP;
  126.       }
  127.  
  128.     else if (strcmp(p[i],"EMI") == 0 ||
  129.              strncmp(p[i],"EMI:",4) == 0) { /* EMI-list requested        */
  130.       lp[P_EMI].priv[0] = SYSOP;        /* first/only default: SYSOP     */
  131.       if (p[i][3] == ':')
  132.         if (conv_priv(&p[i][4],lp[P_EMI].priv,10) <= 0)   /* make int    */
  133.           oper_mode = HELP;
  134.       }
  135.  
  136.     else if (strcmp(p[i],"ALL") == 0 ||
  137.              strncmp(p[i],"ALL:",4) == 0) { /* ALL-list requested        */
  138.       lp[P_ALL].priv[0] = SYSOP;        /* first/only default: SYSOP     */
  139.       if (p[i][3] == ':')
  140.         if (conv_priv(&p[i][4],lp[P_ALL].priv,10) <= 0)   /* make int    */
  141.           oper_mode = HELP;
  142.       }
  143.  
  144.     else if (strcmp(p[i],"IPF") == 0 ||
  145.              strncmp(p[i],"IPF:",4) == 0) { /* IPF-list requested        */
  146.       lp[P_IPF].priv[0] = SYSOP;        /* first/only default: SYSOP     */
  147.       if (p[i][3] == ':')
  148.         if (conv_priv(&p[i][4],lp[P_IPF].priv,10) <= 0)   /* make int    */
  149.           oper_mode = HELP;
  150.       }
  151.  
  152.     else if (strcmp(p[i],"IP2") == 0 ||
  153.              strncmp(p[i],"IP2:",4) == 0) { /* IPF2-list requested       */
  154.       lp[P_IP2].priv[0] = SYSOP;        /* first/only default: SYSOP     */
  155.       if (p[i][3] == ':')
  156.         if (conv_priv(&p[i][4],lp[P_IP2].priv,10) <= 0)   /* make int    */
  157.           oper_mode = HELP;
  158.       }
  159.  
  160.     else if (strcmp(p[i],"GBL") == 0 ||
  161.              strncmp(p[i],"GBL:",4) == 0) { /* GBL-list requested        */
  162.       lp[P_GBL].priv[0] = SYSOP;        /* first/only default: SYSOP     */
  163.       if (p[i][3] == ':')
  164.         if (conv_priv(&p[i][4],lp[P_GBL].priv,10) <= 0)   /* make int    */
  165.           oper_mode = HELP;
  166.       }
  167.  
  168.     else if (strcmp(p[i],"DUP") == 0 ||
  169.              strncmp(p[i],"DUP:",4) == 0) {  /* DUP-list requested       */
  170.       lp[P_DUP].priv[0] = SYSOP;        /* default: SYSOP                */
  171.       if (p[i][3] == ':')
  172.         if (conv_priv(&p[i][4],lp[P_DUP].priv,1) <= 0)   /* convert      */
  173.           oper_mode = HELP;
  174.       }
  175.  
  176.     else if (strcmp(p[i],"OK") == 0 ||
  177.              strncmp(p[i],"OK:",3) == 0) {  /* OK-file requested         */
  178.       lp[P_OK].priv[0] = SYSOP;        /* default: SYSOP                 */
  179.       if (p[i][2] == ':')
  180.         if (conv_priv(&p[i][3],lp[P_OK].priv,10) <= 0)   /* make int     */
  181.           oper_mode = HELP;
  182.       }
  183.  
  184.     else if (strcmp(p[i],"FIL") == 0 ||
  185.              strncmp(p[i],"FIL:",4) == 0) { /* FILES.BBS to be generated */
  186.       lp[P_FIL].priv[0] = SYSOP;
  187.       if (p[i][3] == ':') {             /* path specified?               */
  188.         strncpy(filesbbs_path,&p[i][4],79);
  189.         j = strlen(filesbbs_path);
  190.         if (j>0 && filesbbs_path[j-1] != '\\')
  191.           filesbbs_path[j] = '\\';      /* add backslash if needed       */
  192.         }
  193.       }
  194.  
  195.     else if (p[i][0] == '/' || p[i][0] == '-') { /* option flag          */
  196.       switch(c = (char) toupper(p[i][1])) {
  197.         case TRUNC     :
  198.         case WRAP      : for (j=0; j<P_MAX; ++j)
  199.                            lp[j].wrapflag = c;
  200.                          break;
  201.         case ALPHA     :
  202.         case TIMESTAMP :
  203.         case KEEPSEQ   : for (j=0; j<P_MAX; ++j)
  204.                            lp[j].sortflag = c;
  205.                          break;
  206.         case LONGLIST  : for (j=0; j<P_MAX; ++j)
  207.                            lp[j].longflag = c;
  208.                          break;
  209.         case EXCLPRIV  : for (j=0; j<P_MAX; ++j)
  210.                            lp[j].exclflag = c;
  211.                          break;
  212.         case QUIET     :
  213.         case VERBOSE   :
  214.         case HELP      : oper_mode = c;         break;
  215.         case QMARK     : oper_mode = HELP;      break;
  216.         default        : oper_mode = HELP;      break;
  217.         }
  218.       }
  219.  
  220.     else if (0 < (n = atoi(p[i]))) {    /* num_value: list length        */
  221.       lp[P_BBS].max_fil = n;            /* BBS-list length               */
  222.       lp[P_BBS].listflag = ' ';         /* no period (yet?)              */
  223.       lp[P_NEW].max_fil = n;            /* NEW-list length               */
  224.       lp[P_NEW].listflag = ' ';         /* no period (yet?)              */
  225.       lp[P_EMI].max_fil = n;            /* NEW-list length               */
  226.       lp[P_EMI].listflag = ' ';         /* no period (yet?)              */
  227.       j = strlen(p[i]) - 1;             /* offset to last character      */
  228.       c = (char) toupper(p[i][j]);      /* period specification          */
  229.       if (c == 'D' || c == 'W' || c == 'M') {
  230.         lp[P_BBS].listflag = c;         /* BBS-list flag                 */
  231.         lp[P_NEW].listflag = c;         /* NEW-list flag                 */
  232.         lp[P_EMI].listflag = c;         /* EMI-list flag                 */
  233.         }
  234.       }
  235.  
  236.     else if (p[i][0] == '@')            /* config filespec               */
  237.       ;                                 /* skip (processed in pre-scan)  */
  238.  
  239.     else
  240.       fprintf(stderr, MSG_UNK, p[i]);
  241.     }
  242.  
  243.   for (i=0; i<=P_MAX; i++)              /* all report entries            */
  244.     for (j=0; j<10; j++)                /* all privilege entries         */
  245.       if (ABS_MAX_priv < lp[i].priv[j] &&  /* higher than before         */
  246.               HIDDEN+1 > lp[i].priv[j])  /* but only requested reports   */
  247.         ABS_MAX_priv = lp[i].priv[j];    /* revise if needed             */
  248.   }
  249.  
  250. /* --------------------------------- */
  251. /* Process privilege parameterstring */
  252. /* --------------------------------- */
  253. short int conv_priv(char c[],
  254.                     short int p[],
  255.                     unsigned short int n)
  256. {
  257.   unsigned short int i,j,k;             /* counters                      */
  258.  
  259.   for (i=j=0; i<n && c[i]!='\0' && c[i]!=' '; ++i) {
  260.     if (c[i] == '*')                    /* asterisk specified?           */
  261.       p[j] = SYSOP;                     /* system default                */
  262.     else {
  263.       for (k=0; k<HIDDEN-TWIT+1 &&      /* search table                  */
  264.                 priv_name[k][0] != (char) toupper(c[i]);
  265.                 k++);
  266.       p[j] = k + TWIT;                  /* store real privilege          */
  267.       }                                 /* endif                         */
  268.     if (p[j]<=HIDDEN)                   /* hidden or below?              */
  269.       ++j;                              /* count only valid privs        */
  270.     }                                   /* endfor                        */
  271.   for (i=j; i<n; ++i)                   /* remaining priv-values         */
  272.     p[i] = HIDDEN + 1;                  /* undo any previous settings    */
  273.   return(j);                            /* number of valid privs         */
  274.   }
  275.  
  276. /* =================================== */
  277. /* Process DOWNSORT Configuration File */
  278. /* =================================== */
  279. void read_cfg(char ds_cfg[])
  280. {
  281.   FILE *prm;
  282.   char buf[256], c;
  283.   char *value;                          /* ptr to parameter value        */
  284.   short int  i,j,t;
  285.  
  286.   if ((prm = fopen(ds_cfg,"r")) == NULL )
  287.     fprintf(stderr, MSG_OPI, ds_cfg, 2);  /* dummy rc 'file not found'!*/
  288.  
  289.   else {
  290.     if (oper_mode != QUIET)
  291.       fprintf(stdout, MSG_CFG, cfg_path);
  292.  
  293.     while (fgets(buf,255,prm)) {        /* process 1 line at a time      */
  294.  
  295.       switch(parse_keyword(buf,&value)) {
  296.  
  297.         case K_CMT:                     /* Comment and empty lines       */
  298.           break;
  299.  
  300.         case K_TIT:                     /* list title (ALL, NEW, GBL)    */
  301.           for (j=0; j<20 && value[j]!='\0'; j++)
  302.             if (value[j] == '~')        /* replace tilde by blank        */
  303.               value[j] = ' ';
  304.           strncpy(list_title,value,20);
  305.           break;
  306.  
  307.         case K_PRE:                     /* pre-title                     */
  308.           title_line(value,pre_title);
  309.           break;
  310.  
  311.         case K_SUB:                     /* sub-title                     */
  312.           title_line(value,sub_title);
  313.           break;
  314.  
  315.         case K_BOT:                     /* bottom line                   */
  316.           title_line(value,bot_lines);
  317.           break;
  318.  
  319.         case K_ODS:                     /* Orphan Description            */
  320.           strncpy(ORPHAN,value,45);     /* copy file text                */
  321.           break;
  322.  
  323.         case K_NDS:                     /* Missing Description           */
  324.           strncpy(NDS,value,45);        /* copy file text                */
  325.           break;
  326.  
  327.         case K_OFF:                     /* Offline Description           */
  328.           OFFLINE[0] = '\0';            /* erase default string          */
  329.           strncat(OFFLINE,value,14);    /* copy(!) text                  */
  330.           strcat(OFFLINE," ");          /* 1 trailing blank              */
  331.           break;
  332.  
  333.         case K_FNT:                     /* Font for all lists            */
  334.           t = atoi(value);              /* convert to integer            */
  335.           if (t < FONT0 || t > FONT4)   /* range check                   */
  336.             fprintf(stderr, MSG_FNT);
  337.           else
  338.             for (i=0; i<P_MAX; i++)
  339.               lp[i].tfont = t;          /* to all parmlist entries       */
  340.           break;
  341.  
  342.         case K_DAT:                     /* Area.Dat                      */
  343.           strncpy(areadat_path,strupr(value),80);  /* copy file spec     */
  344.           break;
  345.  
  346.         case K_AIN:                     /* AreaINclude                   */
  347.           area_IN_EX = +1;              /* inclusion                     */
  348.           add_area_array(value);        /* add areanames   */
  349.           break;
  350.  
  351.         case K_AEX:                     /* AreaEXclude                   */
  352.           area_IN_EX = -1;              /* exclusion                     */
  353.           add_area_array(value);        /* add areaname    */
  354.           break;
  355.  
  356.         case K_NDE:                     /* non duplicate extension pairs */
  357.           add_ext_array(value);         /* add ext pairs       */
  358.           break;
  359.  
  360.         case K_ASQ:                     /* AreaSequence                  */
  361.           area_seq = (char) toupper(value[0]);  /* take 1st char upperc. */
  362.           break;
  363.  
  364.         case K_AVA:                     /* Strip AVATAR graphics         */
  365.           strip_ava = (char) toupper(value[0]);   /* set switch          */
  366.           break;
  367.  
  368.         case K_NNN:
  369.           if (0 < (t = atoi(value))) {  /* NEW- & BBS-list length        */
  370.             lp[P_BBS].max_fil = t;      /* BBS-list length               */
  371.             lp[P_BBS].listflag = ' ';   /* no period (yet?)              */
  372.             lp[P_NEW].max_fil = t;      /* NEW-list length               */
  373.             lp[P_NEW].listflag = ' ';   /* no period (yet?)              */
  374.             lp[P_EMI].max_fil = t;      /* EMI-list length               */
  375.             lp[P_EMI].listflag = ' ';   /* no period (yet?)              */
  376.             strupr(value);              /* all upper case                */
  377.             c = value[strlen(asciiz(value))-1]; /* last character        */
  378.             if (c == 'D' || c == 'W' || c == 'M') {  /*                  */
  379.               lp[P_BBS].listflag = c;   /* BBS-list flag                 */
  380.               lp[P_NEW].listflag = c;   /* NEW-list flag                 */
  381.               lp[P_EMI].listflag = c;   /* EMI-list flag                 */
  382.               }
  383.             }
  384.           break;
  385.  
  386.         case K_ALL:                     /* create ALL-list(s)            */
  387.           list_parm(P_ALL,value,10);
  388.           break;
  389.  
  390.         case K_IPF:                     /* create IPF-list(s)            */
  391.           list_parm(P_IPF,value,10);
  392.           break;
  393.  
  394.         case K_IP2:                     /* create IPF2-list(s)           */
  395.           list_parm(P_IP2,value,10);
  396.           break;
  397.  
  398.         case K_BBS:                     /* create BBS-list               */
  399.           list_parm(P_BBS,value,1);
  400.           break;
  401.  
  402.         case K_GBL:                     /* create GBL-list               */
  403.           list_parm(P_GBL,value,10);
  404.           break;
  405.  
  406.         case K_NEW:                     /* create NEW-list(s)            */
  407.           list_parm(P_NEW,value,10);
  408.           break;
  409.  
  410.         case K_EMI:                     /* create EMI-list(s)            */
  411.           list_parm(P_EMI,value,10);
  412.           break;
  413.  
  414.         case K_DUP:                     /* naming of DUP-list            */
  415.           list_parm(P_DUP,value,1);
  416.           break;
  417.  
  418.         case K_OK:                      /* create OKfile(s)              */
  419.           list_parm(P_OK,value,10);
  420.           break;
  421.  
  422.         case K_ORP:                     /* naming of ORP-list            */
  423.           list_parm(P_ORP,value,1);
  424.           break;
  425.  
  426.         case K_FIL:                     /* create FILES.bbs files        */
  427.           strupr(value);                /* all upper case                */
  428.           conv_priv(value,lp[P_FIL].priv,1);
  429.           while ((value = next_word(value)) != NULL) {  /* remaining prms*/
  430.             if (value[0] == '/' || value[0] == '-') {  /* option flag    */
  431.               switch(value[1]) {
  432.                 case ALPHA     : lp[P_FIL].sortflag = ALPHA;     break;
  433.                 case TIMESTAMP : lp[P_FIL].sortflag = TIMESTAMP; break;
  434.                 case KEEPSEQ   : lp[P_FIL].sortflag = KEEPSEQ;   break;
  435.                 case EXCLPRIV  : lp[P_FIL].exclflag = EXCLPRIV;  break;
  436.                 case LONGLIST  : lp[P_FIL].longflag = LONGLIST;  break;
  437.                 case INCLUDE   : lp[P_FIL].incl_fspec =
  438.                                     (char *)malloc(strlen(asciiz(value+2))+1);
  439.                                  if (lp[P_FIL].incl_fspec == NULL) {
  440.                                    fprintf(stderr,MSG_MEM,PROGNAME);
  441.                                    exit(14);
  442.                                    }
  443.                                  else
  444.                                    strcpy(lp[P_FIL].incl_fspec,
  445.                                                  asciiz(value+2));
  446.                                  break;
  447.                 case FONT      : t = atoi(value+2);
  448.                                  if (t >= FONT0 && t <= FONT4) /* range */
  449.                                    lp[P_FIL].tfont = t;
  450.                                  break;
  451.                 default        : break;
  452.                 }
  453.               }
  454.             else {                      /* assume 'value' is pathname    */
  455.               strncpy(filesbbs_path,asciiz(value),80); /* spec'd PATH    */
  456.               j = strlen(filesbbs_path);
  457.               if (j>0 && filesbbs_path[j-1] != '\\')
  458.                 filesbbs_path[j] = '\\';    /* add backslash if needed   */
  459.               }
  460.             }
  461.           break;
  462.  
  463.         case K_END:                     /* Keyword not found             */
  464.         default:                        /* undefined                     */
  465.           fprintf(stderr, MSG_KWD, buf); /* keyword or value problem     */
  466.           break;
  467.         }
  468.       }
  469.     fclose(prm);                        /* close downsort.cfg            */
  470.     }
  471.   }
  472.  
  473. /* =============================== */
  474. /* Process xxxFileList parameters. */
  475. /* =============================== */
  476. void list_parm(short int k,
  477.                char  *v,
  478.                short int n)
  479. {
  480.   short int  t,j;                       /* intermediate int value        */
  481.   char *nv;                             /* moving string pointer         */
  482.   char c;                               /* single input character        */
  483.  
  484.   strupr(v);                            /* whole string uppercase        */
  485.   conv_priv(v, lp[k].priv, n);          /* privilege string              */
  486.   if ((nv = next_word(v)) != NULL  &&   /* 1st expected: filename        */
  487.        strcmp(nv,"*") != 0)             /* not asterisk                  */
  488.     strncpy(lp[k].name,asciiz(nv),8);   /* customised filename           */
  489.   while ((nv = next_word(nv)) != NULL) { /* remaining parm(s)            */
  490.     if (nv[0] == '/' || nv[0] == '-') { /* option flag                   */
  491.       switch(nv[1]) {
  492.         case TRUNC     : lp[k].wrapflag = TRUNC;     break;
  493.         case WRAP      : lp[k].wrapflag = WRAP;      break;
  494.         case ALPHA     : lp[k].sortflag = ALPHA;     break;
  495.         case TIMESTAMP : lp[k].sortflag = TIMESTAMP; break;
  496.         case KEEPSEQ   : lp[k].sortflag = KEEPSEQ;   break;
  497.         case LONGLIST  : lp[k].longflag = LONGLIST;  break;
  498.         case FONT      : t = atoi(nv+2);
  499.                          if (t >= FONT0 && t <= FONT4) /* range check    */
  500.                            lp[k].tfont = t;
  501.                          break;
  502.         case EXCLPRIV  : lp[k].exclflag = EXCLPRIV;  break;
  503.         case INCLUDE   : lp[k].incl_fspec =
  504.                                   (char *)malloc(strlen(asciiz(nv+2))+1);
  505.                          if (lp[k].incl_fspec == NULL) {
  506.                            fprintf(stderr, MSG_MEM, PROGNAME);  /* mem   */
  507.                            exit(14);
  508.                            }
  509.                          else
  510.                            strcpy(lp[k].incl_fspec, asciiz(nv+2));
  511.                          break;
  512.         default        : break;         /* invalid parms ignored         */
  513.         }
  514.       }
  515.     else if (0 < atoi(nv)) {            /* numeric: NEW-list length      */
  516.       lp[k].max_fil = atoi(nv);         /* (for IPF-list: pagesize)      */
  517.       lp[k].listflag = ' ';             /* set to (nullify previous) peri*/
  518.       j = strlen(asciiz(nv)) - 1;       /* offset to last character      */
  519.       c = nv[j];                        /* last character                */
  520.       if (c == 'D' || c == 'W' || c == 'M')
  521.         lp[k].listflag = c;             /* copy listflag                 */
  522.       }
  523.     }
  524.   }
  525.  
  526. /* ============================ */
  527. /* Process xxxTitle parameters. */
  528. /* ============================ */
  529. void  title_line(char *v,
  530.                  char *t[])
  531. {
  532.   short int i,j;                        /* counters                      */
  533.  
  534.   for (i=0; i<MAXTIT && t[i]!=NULL; ++i);  /* search 1st free place      */
  535.   if (i<MAXTIT) {                       /* not too many subtitles?       */
  536.     t[i] = (char *)malloc(strlen(v)+2); /* obtain memory (1 too many?)   */
  537.     if (t[i] == NULL) {
  538.       fprintf(stderr,MSG_MEM, PROGNAME);   /* not enough memory          */
  539.       exit(14);
  540.       }
  541.     else {
  542.       for (j=0; v[j]; j++)              /* whole line                    */
  543.         t[i][j] = (char)((v[j] == '~') ? ' ' : v[j]);  /* copy/translate */
  544.       t[i][j] = '\0';                   /* end of string                 */
  545.       }
  546.     }
  547.   }
  548.  
  549. /* ============================ */
  550. /* Process AreaSelect line      */
  551. /* ============================ */
  552. void  add_area_array(char  *v)          /* ptr to 1st areaname */
  553. {
  554.   short int i,j;                        /* counters                      */
  555.  
  556.   for (i=0; selected_area[i][0] != '\0'; ++i);  /* search first empty    */
  557.   for ( ; v!=NULL && i<200; i++) {      /* all entries in array bounds   */
  558.     for (j=0; v[j] != ' ' && v[j] != '\0' && j < MAXANAME-1; ++j)
  559.        selected_area[i][j] = v[j];      /* copy area name to array       */
  560.     for ( ; j < MAXANAME; ++j)
  561.        selected_area[i][j] = '\0';      /* trailing zero's               */
  562.     v = next_word(v);                   /* search next code              */
  563.     }
  564.   selected_area[i][0] = '\0';           /* last entry marker             */
  565.   }
  566.  
  567. /* ================================ */
  568. /* Process Non Duplicate Extensions */
  569. /* ================================ */
  570. void  add_ext_array(char  *v)            /* ptr to 1st ext of 1st pair */
  571. {
  572.   short int i,j;                        /* counters                      */
  573.  
  574.   for (i=0; non_dup_ext[i][0] != '\0'; ++i);  /* search first empty    */
  575.   for ( ; v!=NULL && i<200; i++) {      /* all entries in array bounds   */
  576.     for (j=0; v[j] != ' ' && v[j] != '\0' && j < 3; ++j)
  577.        non_dup_ext[i][j] = v[j];          /* copy area name to array       */
  578.     for ( ; j < 3; ++j)
  579.        non_dup_ext[i][j] = '\0';          /* trailing zero's               */
  580.     v = next_word(v);                   /* search next code              */
  581.     }
  582.   non_dup_ext[i][0] = '\0';               /* last entry marker             */
  583.   }
  584.  
  585. /* ===================================== */
  586. /* Find the number of the config options */
  587. /* Returns the keyword symbolic number,  */
  588. /* and pointer to the keyword value.     */
  589. /* ===================================== */
  590. short int parse_keyword(char line[],
  591.                         char **value)
  592. {
  593.   short int i,p;                        /* counters                      */
  594.  
  595.   static struct parse_config {          /* Keyword Parameter Spec        */
  596.        unsigned char id;                /* parameter identifier          */
  597.        unsigned char len;               /* keyword length                */
  598.        char *key;                       /* keyword                       */
  599.        } cfg[] = {                      /* table of keyword parameters   */
  600.                                         /* NOTE: most significant first! */
  601.            {K_ALL, 11, "AllFileList"},
  602.            {K_DAT,  7, "AreaDat"},
  603.            {K_AEX, 11, "AreaEXclude"},
  604.            {K_AIN, 11, "AreaINclude"},
  605.            {K_ASQ,  9, "AreaOrder"},
  606.            {K_AVA,  8, "AVAstrip"},
  607.            {K_BBS, 11, "BbsFileList"},
  608.            {K_BOT, 10, "BottomLine"},
  609.            {K_DUP, 11, "DupFileList"},
  610.            {K_EMI, 11, "EmiFileList"},
  611.            {K_FIL, 11, "FilFilePath"},
  612.            {K_GBL, 11, "GblFileList"},
  613.            {K_IPF, 11, "IpfFileList"},
  614.            {K_IP2, 11, "Ip2FileList"},
  615.            {K_NNN, 11, "MaxNewFiles"},
  616.            {K_NEW, 11, "NewFileList"},
  617.            {K_NDE,  9, "NonDupEXT"},
  618.            {K_OK,  10, "OKFileList"},
  619.            {K_NDS, 12, "NotFoundDesc"},
  620.            {K_OFF, 11, "OfflineDesc"},
  621.            {K_ORP, 11, "OrpFileList"},
  622.            {K_ODS, 10, "OrphanDesc"},
  623.            {K_PRE,  8, "PreTitle"},
  624.            {K_SUB,  8, "SubTitle"},
  625.            {K_FNT,  9, "TitleFont"},
  626.            {K_TIT,  5, "Title"},
  627.            {K_END,  0, ""},             /* end of table: keyw. not found */
  628.              };
  629.  
  630.   *value = NULL;                        /* init: default return          */
  631.  
  632.   for (i=0; line[i]==' '; ++i);         /* skip leading blanks           */
  633.   line = line+i;                        /* new local pointer             */
  634.  
  635.   if (line[0] == '%'  ||                /* comment                       */
  636.       line[0] == ';'  ||                /* comment                       */
  637.       line[0] == '*'  ||                /* comment                       */
  638.       line[0] == '\r' ||                /* CR character                  */
  639.       line[0] == '\n' ||                /* LF character                  */
  640.       line[0] == '\0')                  /* end of string                 */
  641.     return(K_CMT);                      /* return as comment line        */
  642.  
  643.   for (i=0; cfg[i].id < K_END &&        /* search keyword                */
  644.            strnicmp(line,cfg[i].key,cfg[i].len) != 0 ; i++);
  645.   p = cfg[i].id;                        /* return identification value   */
  646.  
  647.   *value = next_word(line);             /* search value string           */
  648.   if (*value == NULL)                   /* no keyword value              */
  649.     return(K_END);                      /* treat as invalid keyword      */
  650.  
  651.   i = strlen(*value);                   /* length of value string        */
  652.   if ((*value)[i-1] == '\n'  ||         /* line feed or                  */
  653.       (*value)[i-1] == '\r')            /* carriage return               */
  654.     (*value)[i-1] = '\0';               /* replaced by end of string     */
  655.  
  656.   return(p);                            /* return the keyword number     */
  657.   }
  658.  
  659.